/*
 * Sii Core Base Application
 *
 * Copyright (c) 2011 Sii Sp. z o.o. All rights reserved.
 */
package com.gdziarmaga.webshop.utils.filtering;

import java.util.Collection;

import org.hibernate.Criteria;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;
import org.hibernate.util.StringHelper;


/**
 * Filter object used to construct multi field filter. It uses {@link Criteria}
 * with {@link Restrictions}.
 * 
 * @author Wojciech Kochman
 * @version 1.0
 * 
 */
public class GenericFilter {

    /**
     * serialVersionUID.
     */
    private static final long serialVersionUID = 966452861950947325L;
    
    private BaseFilter baseFilter;
    
    /**
     * Constructor 
     * @param baseFilter - provided filter 
     */
    public GenericFilter(BaseFilter baseFilter) {
        this.baseFilter = baseFilter;
    }

    /**
     * Getter for instance of {@link BaseFilter}
     * @return the baseFilter
     */
    public BaseFilter getBaseFilter() {
        return baseFilter;
    }
    
    /**
     * Adds {@link Restrictions} to {@link Criteria} object base on
     * {@link FilterField} stored in object.
     * 
     * @param criteria the {@link Criteria} to add {@link Restrictions}
     */
    public void addRestrictionFromFilterFields(DetachedCriteria criteria) {
        if (criteria != null && baseFilter.getFilterFields() != null && !baseFilter.getFilterFields().isEmpty()) {
            for (FilterField<?> field : baseFilter.getFilterFields()) {
                String fieldName = field.getFieldName();
                Object value = field.getValue();
                MatchMode matchMode = field.getMatchMode();
//                MatchMode matchMode = FilterMatchModeConverter.convertToMatchMode(field.getMatchMode());
                if (value instanceof String && StringHelper.isEmpty((String) value)) {
                    value = null;
                }
                if (value != null) {
                    switch (field.getComparisonType()) {
                    case EQUAL:
                        criteria.add(Restrictions.eq(fieldName, value));
                        break;
                    case LIKE:
                        criteria.add(Restrictions.like(fieldName, (String) value, matchMode));
                        break;
                    case LIKE_CASE_INSENSITIVE:
                        criteria.add(Restrictions.ilike(fieldName, (String) value, matchMode));
                        break;
                    case GREATER:
                        criteria.add(Restrictions.gt(fieldName, value));
                        break;
                    case GREATER_EQUAL:
                        criteria.add(Restrictions.ge(fieldName, value));
                        break;
                    case LESS:
                        criteria.add(Restrictions.lt(fieldName, value));
                        break;
                    case LESS_EQUAL:
                        criteria.add(Restrictions.le(fieldName, value));
                        break;
                    case IN:
                        criteria.add(Restrictions.in(fieldName, ((Collection<?>) value).toArray()));
                        break;
                    default:
                        criteria.add(Restrictions.eq(fieldName, value));

                    }
                }
            }
        }
    }

    /**
     * Adds {@link Restrictions} to {@link Criteria} object base on
     * {@link FilterField} stored in object.
     * 
     * @param criteria the {@link Criteria} to add {@link Restrictions}
     */
    public void addRestrictionFromFilterFields(Criteria criteria) {
        if (criteria != null && baseFilter.getFilterFields() != null && !baseFilter.getFilterFields().isEmpty()) {
            for (FilterField<?> field : baseFilter.getFilterFields()) {
                String fieldName = field.getFieldName();
                Object value = field.getValue();
                MatchMode matchMode = field.getMatchMode();
//                MatchMode matchMode = FilterMatchModeConverter.convertToMatchMode(field.getMatchMode());
                if (value instanceof String && StringHelper.isEmpty((String) value)) {
                    value = null;
                }
                if (value != null) {
                    switch (field.getComparisonType()) {
                    case EQUAL:
                        criteria.add(Restrictions.eq(fieldName, value));
                        break;
                    case LIKE:
                        criteria.add(Restrictions.like(fieldName, (String) value, matchMode));
                        break;
                    case LIKE_CASE_INSENSITIVE:
                        criteria.add(Restrictions.ilike(fieldName, (String) value, matchMode));
                        break;
                    case GREATER:
                        criteria.add(Restrictions.gt(fieldName, value));
                        break;
                    case GREATER_EQUAL:
                        criteria.add(Restrictions.ge(fieldName, value));
                        break;
                    case LESS:
                        criteria.add(Restrictions.lt(fieldName, value));
                        break;
                    case LESS_EQUAL:
                        criteria.add(Restrictions.le(fieldName, value));
                        break;
                    case IN:
                        criteria.add(Restrictions.in(fieldName, ((Collection<?>) value).toArray()));
                        break;
                    default:
                        criteria.add(Restrictions.eq(fieldName, value));

                    }
                }
            }
        }
    }

}
